﻿using OfficeOpenXml;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.RegularExpressions;

namespace GetGitlabInfoDemo
{
    internal class Program
    {

        private static readonly string ACCESS_TOKEN = "glpat--xooHa3zEKtsm-kKU1uV";
        private static readonly string GITLAB_URL = "https://gitlab.wayzim.net";

        static async Task Main(string[] args)
        {
            Console.Write("请输入开始日期 (YYYY-MM-DD): ");
            string since = Console.ReadLine();
            Console.Write("请输入结束日期 (YYYY-MM-DD): ");
            string until = Console.ReadLine();

            var projects = await GetAllProjects();
            var allCommits = new List<CommitData>();

            foreach (var project in projects)
            {
                var commits = await GetCommits(project.id, since, until);
                foreach (var commit in commits)
                {
                    var comments = await GetCommitComments(project.id, commit.Id);
                    //var (filePaths, linesChanged) = await GetCommitDiff(project.id, commit.Id);
                    var averageScore = CalculateAverageScore(comments);
                    var commitLink = $"{GITLAB_URL}/{project.PathWithNamespace}/-/commit/{commit.Id}";

                    // 提取提交类型
                    var commitType = ExtractCommitType(commit.Message);

                    allCommits.Add(new CommitData
                    {
                        ProjectName = project.PathWithNamespace,
                        Author = commit.AuthorName,
                        CommitDate = commit.CommittedDate,
                        CommitMessage = commit.Message,
                        CommitType = commitType, // 添加提交类型
                        Comments = string.Join("\n", comments.Select(c => $"{c.Author.Name}: {c.Note}")),
                        CommitLink = commitLink,
                        Reviewers = string.Join(", ", comments.Select(c => c.Author.Name).Distinct()),
                        //LinesChanged = linesChanged,
                        AverageScore = averageScore
                    });
                }
            }

            ExportToExcel(allCommits);
        }

        //private static async Task<List<Project>> GetProjects()
        //{
        //    using var client = new HttpClient();
        //    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ACCESS_TOKEN);
        //    var response = await client.GetAsync($"{GITLAB_URL}/api/v4/projects?per_page=100");
        //    response.EnsureSuccessStatusCode();
        //    var json = await response.Content.ReadAsStringAsync();
        //    return JsonSerializer.Deserialize<List<Project>>(json);
        //}

        public static async Task<List<Project>> GetAllProjects()
        {
            List<Project> allProjects = new List<Project>();
            int page = 1;
            int perPage = 100; // 每页返回的项目数量

            while (true)
            {
                try
                {
                    using var client = new HttpClient();
                    // 构建请求 URL，包含分页参数
                    var requestUrl = $"https://gitlab.wayzim.net/api/v4/projects?per_page={perPage}&page={page}";
                    var response = await client.GetAsync(requestUrl);
                    response.EnsureSuccessStatusCode();

                    var jsonResponse = await response.Content.ReadAsStringAsync();
                    var projects = JsonSerializer.Deserialize<List<Project>>(jsonResponse);

                    if (projects == null || projects.Count == 0)
                    {
                        break; // 如果没有更多项目，退出循环
                    }

                    allProjects.AddRange(projects);
                    page++; // 增加页码以获取下一页
                }
                catch (HttpRequestException e)
                {
                    Console.WriteLine($"请求错误: {e.Message}");
                    break; // 出现错误时退出循环
                }
                catch (JsonException e)
                {
                    Console.WriteLine($"JSON 解析错误: {e.Message}");
                    break; // 出现解析错误时退出循环
                }
            }

            return allProjects;
        }

        private static async Task<List<Commit>> GetCommits(int projectId, string since, string until)
        {
            using var client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ACCESS_TOKEN);
            var response = await client.GetAsync($"{GITLAB_URL}/api/v4/projects/{projectId}/repository/commits?since={since}&until={until}");
            response.EnsureSuccessStatusCode();
            var json = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<List<Commit>>(json);
        }

        private static async Task<List<Comment>> GetCommitComments(int projectId, string commitSha)
        {
            using var client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ACCESS_TOKEN);
            var response = await client.GetAsync($"{GITLAB_URL}/api/v4/projects/{projectId}/repository/commits/{commitSha}/comments");
            response.EnsureSuccessStatusCode();
            var json = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<List<Comment>>(json);
        }

        private static async Task<(List<string> filePaths, int linesChanged)> GetCommitDiff(int projectId, string commitSha)
        {
            using var client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ACCESS_TOKEN);
            var response = await client.GetAsync($"{GITLAB_URL}/api/v4/projects/{projectId}/repository/commits/{commitSha}/diff");
            response.EnsureSuccessStatusCode();
            var json = await response.Content.ReadAsStringAsync();
            var diffs = JsonSerializer.Deserialize<List<Diff>>(json);

            var filePaths = diffs.Select(d => d.NewPath).ToList();
            int linesChanged = diffs.Sum(d => d.diff.Count(line => line.StartsWith("+") || line.StartsWith("-")));

            return (filePaths, linesChanged);
        }

        private static double CalculateAverageScore(List<Comment> comments)
        {
            var scores = new List<int>();
            foreach (var comment in comments)
            {
                var scoreMatch = Regex.Match(comment.Note, @"\[(\d+)\]");
                if (scoreMatch.Success)
                {
                    scores.Add(int.Parse(scoreMatch.Groups[1].Value));
                }
            }
            return scores.Count > 0 ? (double)scores.Sum() / scores.Count : 0;
        }

        private static string ExtractCommitType(string commitMessage)
        {
            // 假设提交类型是通过提取提交信息中的特定标签来定义的
            var match = Regex.Match(commitMessage, @"\[(.*?)\]");
            return match.Success ? match.Groups[1].Value : "No Type"; // 返回标签或默认值
        }

        private static void ExportToExcel(List<CommitData> commits)
        {
            using var package = new ExcelPackage();
            var worksheet = package.Workbook.Worksheets.Add("GitLab Data");

            // 设置表头
            worksheet.Cells[1, 1].Value = "工程名称";
            worksheet.Cells[1, 2].Value = "作者";
            worksheet.Cells[1, 3].Value = "提交日期";
            worksheet.Cells[1, 4].Value = "哈希值";
            worksheet.Cells[1, 5].Value = "提交信息";
            worksheet.Cells[1, 6].Value = "提交类型"; // 添加提交类型列
            worksheet.Cells[1, 7].Value = "评论";
            worksheet.Cells[1, 8].Value = "提交链接";
            worksheet.Cells[1, 9].Value = "评论人";
            worksheet.Cells[1, 10].Value = "行数";
            worksheet.Cells[1, 11].Value = "平均分";

            // 填充数据
            for (int i = 0; i < commits.Count; i++)
            {
                worksheet.Cells[i + 2, 1].Value = commits[i].ProjectName;
                worksheet.Cells[i + 2, 2].Value = commits[i].Author;
                worksheet.Cells[i + 2, 3].Value = commits[i].CommitDate;
                worksheet.Cells[i + 2, 4].Value = commits[i].Id; // 提交哈希值
                worksheet.Cells[i + 2, 5].Value = commits[i].CommitMessage;
                worksheet.Cells[i + 2, 6].Value = commits[i].CommitType; // 填充提交类型
                worksheet.Cells[i + 2, 7].Value = commits[i].Comments;
                worksheet.Cells[i + 2, 8].Value = commits[i].CommitLink;
                worksheet.Cells[i + 2, 9].Value = commits[i].Reviewers;
                worksheet.Cells[i + 2, 10].Value = commits[i].LinesChanged;
                worksheet.Cells[i + 2, 11].Value = commits[i].AverageScore;
            }

            // 保存Excel文件
            package.SaveAs(new FileInfo("gitlab_data.xlsx"));
        }
    }

    public class Project
    {
        public int id { get; set; }
        public string name { get; set; }
        public string NameWithNamespace { get; set; }
        public string Path { get; set; }
        public string PathWithNamespace { get; set; }
        public string CreatedAt { get; set; }
        public string DefaultBranch { get; set; }
        public string SshUrlToRepo { get; set; }
        public string HttpUrlToRepo { get; set; }
        public string WebUrl { get; set; }
        public bool EmptyRepo { get; set; }
        public bool Archived { get; set; }
        public string Visibility { get; set; }
        public Namespace Namespace { get; set; }
        // 添加其他必要的字段
    }

    public class Namespace
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Path { get; set; }
        public string Kind { get; set; }
        public string FullPath { get; set; }
        // 添加其他必要的字段
    }

    public class Commit
    {
        public string Id { get; set; }
        public string AuthorName { get; set; }
        public string CommittedDate { get; set; }
        public string Message { get; set; }
    }

    public class Comment
    {
        public string Note { get; set; }
        public Author Author { get; set; }
    }

    public class Author
    {
        public string Name { get; set; }
    }

    public class Diff
    {
        public string NewPath { get; set; }
        public List<string> diff { get; set; }
    }

    public class CommitData
    {
        public string ProjectName { get; set; }
        public string Author { get; set; }
        public string CommitDate { get; set; }
        public string Id { get; set; } // 提交哈希值
        public string CommitMessage { get; set; }
        public string CommitType { get; set; } // 提交类型
        public string Comments { get; set; }
        public string CommitLink { get; set; }
        public string Reviewers { get; set; }
        public int LinesChanged { get; set; }
        public double AverageScore { get; set; }
    }
}
